import { Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import {InjectEntityModel} from "@midwayjs/typeorm";
import {Repository} from "typeorm";
import {DemoShipsEntity} from "../../../demo/entity/ships";
import {DemoShipDataEntity} from "../../../demo/entity/ship_data";
import {DemoPlayerDataEntity} from "../../../demo/entity/player_data";

const aedes = require('aedes')()
const httpServer = require('http').createServer()
const WebSocket = require('ws')
const wsPort = 8012

const MqttServer = require('net').createServer(aedes.handle)
const port = 61613
/**
 * apk信息
 */
@Provide()
export class CommService extends BaseService {

  @InjectEntityModel(DemoShipsEntity)
  demoShipsEntity: Repository<DemoShipsEntity>;

  @InjectEntityModel(DemoShipDataEntity)
  demoShipDataEntity: Repository<DemoShipDataEntity>;

  @InjectEntityModel(DemoPlayerDataEntity)
  demoPlayerDataEntity: Repository<DemoPlayerDataEntity>;

  async initMqtt(){
    // Here we are creating the Websocket Server that is using the HTTP Server...
    const wss = new WebSocket.Server({ server: httpServer })
    wss.on('connection', function connection (ws) {
      const duplex = WebSocket.createWebSocketStream(ws)
      aedes.handle(duplex)
    })

    httpServer.listen(wsPort, () => {
      console.log('websocket监听端口=====》', wsPort)
    })

    MqttServer.listen(port, function () {
      console.log('MqttServer started and listening on port ', port)
    });

    // 客户端连接
    aedes.on('client', async (client) => {
      await this.demoShipsEntity.update({sn: client.id},{online: 1})
      console.log('连接成功',client.id);
    });

    aedes.on('clientError', function (client) {
      console.log('连接失败',client.id);
    });

    // 客户端断开
    aedes.on('clientDisconnect', async (client) => {
      await this.demoShipsEntity.update({sn: client.id},{online: 0})
      console.log('断开连接: \x1b[31m' + (client ? client.id : client) + '\x1b[0m', 'to broker', aedes.id);
    });

    aedes.on('publish', async (packet, client) => {
      // if (packet && packet.payload) {
      //   console.log('发布数据包=======》', packet.payload.toString())
      // }
      if (client) {

        let data = await this.demoShipsEntity.findOneBy({sn: client.id}),publishData,publishArr,mqttArr,shipDataArr,playerDataArr,
          name1,name2,name3,name4,name5,name6,name7,name8,gender1,gender2,gender3,gender4,gender5,gender6,gender7,gender8
        if (data && data.storeState == 1 && packet.payload.toString().indexOf('$,,,,,,,,,,;') != -1){
          publishData = packet.payload.toString()
          publishData = publishData.substring(0,publishData.lastIndexOf('$'))
          publishArr = publishData.split('$');
          // console.log(publishArr)

          publishArr.map(async (item,index1) => {
            mqttArr = item.split(';');
            if (index1 == 0){
              mqttArr.map(async (item,index2) => {
                switch (index2) {
                  case 0:
                    shipDataArr = item.split(',')
                    await this.demoShipDataEntity.insert({
                      sn: data.sn,
                      shipId: data.id,
                      pitchAngle: (shipDataArr[3]/100).toString(),
                      obliqueAngle: (shipDataArr[4]/100).toString(),
                      lng: shipDataArr[5],
                      lat: shipDataArr[6],
                      averageSpeed: shipDataArr[8] //目前存的是船实际速度
                    })
                    break
                  case 1:
                    playerDataArr = item.split(',')
                    name1 = playerDataArr[1]
                    gender1 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 1,
                      shipId: data.id,
                      playerName: name1,
                      gender: gender1,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 2:
                    playerDataArr = item.split(',')
                    name2 = playerDataArr[1]
                    gender2 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 2,
                      shipId: data.id,
                      playerName: name2,
                      gender: gender2,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 3:
                    playerDataArr = item.split(',')
                    name3 = playerDataArr[1]
                    gender3 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 3,
                      shipId: data.id,
                      playerName: name3,
                      gender: gender3,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 4:
                    playerDataArr = item.split(',')
                    name4 = playerDataArr[1]
                    gender4 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 4,
                      shipId: data.id,
                      playerName: name4,
                      gender: gender4,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 5:
                    playerDataArr = item.split(',')
                    name5 = playerDataArr[1]
                    gender5 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 5,
                      shipId: data.id,
                      playerName: name5,
                      gender: gender5,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 6:
                    playerDataArr = item.split(',')
                    name6 = playerDataArr[1]
                    gender6 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 6,
                      shipId: data.id,
                      playerName: name6,
                      gender: gender6,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 7:
                    playerDataArr = item.split(',')
                    name7 = playerDataArr[1]
                    gender7 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 7,
                      shipId: data.id,
                      playerName: name7,
                      gender: gender7,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 8:
                    playerDataArr = item.split(',')
                    name8 = playerDataArr[1]
                    gender8 = playerDataArr[2]
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 8,
                      shipId: data.id,
                      playerName: name8,
                      gender: gender8,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                }
              })
            }else {
              mqttArr.map(async (item,index2) => {
                switch (index2) {
                  case 0:
                    break
                  case 1:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 1,
                      shipId: data.id,
                      playerName: name1,
                      gender: gender1,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 2:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 2,
                      shipId: data.id,
                      playerName: name2,
                      gender: gender2,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 3:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 3,
                      shipId: data.id,
                      playerName: name3,
                      gender: gender3,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 4:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 4,
                      shipId: data.id,
                      playerName: name4,
                      gender: gender4,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 5:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 5,
                      shipId: data.id,
                      playerName: name5,
                      gender: gender5,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 6:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 6,
                      shipId: data.id,
                      playerName: name6,
                      gender: gender6,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 7:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 7,
                      shipId: data.id,
                      playerName: name7,
                      gender: gender7,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                  case 8:
                    playerDataArr = item.split(',')
                    await this.demoPlayerDataEntity.insert({
                      paddleId: 8,
                      shipId: data.id,
                      playerName: name8,
                      gender: gender8,
                      verticalPower: playerDataArr[3],
                      pressure: playerDataArr[8],
                      velocity: playerDataArr[9],
                      paddleAngle: (playerDataArr[10]/100).toString()
                    })
                    break
                }
              })
            }
            // console.log(mqttArr)
          })
        }
        // console.log(data)
        console.log('客户端信息=======》', client.id)
        // console.log('发布数据包=======》', packet.payload.toString())
        console.log(packet.payload.toString().indexOf('$,,,,,,,,,,;'))
      }
    })

    aedes.on('subscribe', (subscriptions, client) => {
      if (client) {
        console.log('订阅==========》', subscriptions, client.id)
      }
    })
  }
}
